package com.bosssoft.trainee.nontax.controller;

import com.alibaba.fastjson.JSONObject;
import com.bosssoft.trainee.nontax.annotation.PassToken;
import com.bosssoft.trainee.nontax.annotation.UserLoginToken;
import com.bosssoft.trainee.nontax.common.result.CodeMsg;
import com.bosssoft.trainee.nontax.common.result.Result;
import com.bosssoft.trainee.nontax.entity.dto.TokenResult;
import com.bosssoft.trainee.nontax.entity.dto.UserInfo;
import com.bosssoft.trainee.nontax.entity.vo.UserVo;
import com.bosssoft.trainee.nontax.service.jwt.TokenService;
import com.bosssoft.trainee.nontax.service.UserService;
import com.bosssoft.trainee.nontax.util.mapper.dtoVo.UserDtoVo;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import java.util.Objects;


/**
 * @Description: login controller
 * @Author: Luo WenLong
 * @Date: 2022/6/24 13:50
 */
@Slf4j
@Controller
public class LoginController {
    @Autowired
    private UserService userService;

    @Autowired
    private TokenService tokenService;

    @Autowired
    private UserDtoVo userDtoVo;


    /**
     * @Description: 用户登录验证
     * @param jsonObject jsonObject用于接受参数
     * @return: com.bosssoft.trainee.nontax.common.result.Result<com.bosssoft.trainee.nontax.entity.dto.TokenResult>
     * @Author: Luo WenLong
     * @Date: 2022/6/24 11:25
     */

    @PassToken
    @RequestMapping("/user/login")
    @ResponseBody
    @HystrixCommand(fallbackMethod = "loginHystrix")
    public Result<TokenResult> login(@RequestBody JSONObject jsonObject) {
        // get param
        Integer username = jsonObject.getInteger("username");
        String password = jsonObject.getString("password");
        log.info("login " + username + ":" + password);
        // validate user
        UserVo user = userService.queryById(username);
        if (user == null) {
            return Result.error(CodeMsg.USER_NOT_EXIST);
        } else if (!Objects.equals(user.getPassword(), password)) {
            return Result.error(CodeMsg.USER_OR_PASS_ERROR);
        }

        TokenResult tokenResult = new TokenResult();
        String token = tokenService.getToken(userDtoVo.vo2dto(user));
        tokenResult.setToken(token);
        return Result.success(tokenResult);
    }

    public Result<TokenResult> loginHystrix(JSONObject jsonObject) {
        return Result.success(TokenResult.builder().token("no use token, generate by hystrix").build());
    }

    /**
     * @Description: 获取用户信息，通过user info的形式返回
     * @param token token
     * @return: com.bosssoft.trainee.nontax.common.result.Result<com.bosssoft.trainee.nontax.entity.dto.UserInfo>
     * @Author: Luo WenLong
     * @Date: 2022/6/24 22:33
     */
    @UserLoginToken
    @RequestMapping("/user/info")
    @ResponseBody
    @HystrixCommand(fallbackMethod = "getInfoHystrix")
    public Result<UserInfo> getInfo(@RequestParam String token) {
        Integer userId = tokenService.getUserIdFromToken(token);
        if(userId == null) {
            return Result.error(CodeMsg.TOKEN_ERROR);
        }
        UserVo user = userService.queryById(userId);
        if(user == null){
            return Result.error(CodeMsg.USER_NOT_EXIST);
        }
        log.info("get user info by user id: " + user.getUserId());
        UserInfo userInfo = userService.getUserInfoFromUser(userDtoVo.vo2dto(user));
        return Result.success(userInfo);
    }

    public Result<UserInfo> getInfoHystrix(@RequestParam String token) {
        return Result.success(UserInfo.builder().name("系统繁忙").introduction("系统繁忙，请稍后再试").build());
    }

    /**
     * @Description: 退出登录
     * @param: null
     * @return: com.bosssoft.trainee.nontax.common.result.Result<java.lang.Object>
     * @Author: Luo WenLong
     * @Date: 2022/6/24 22:34
     */
    @PassToken
    @RequestMapping("/user/logout")
    @ResponseBody
    @HystrixCommand(fallbackMethod = "logoutHystrix")
    public Result<Object> logout() {
        log.info("logout");
        return Result.success();
    }

    public Result<Object> logoutHystrix() {
        log.info("logout");
        return Result.error(CodeMsg.HYSTRIX_METHOD);
    }
}